using System;
using System.Threading;
using System.Collections.Generic;
using System.Collections;
using System.Drawing;
using System.Text;

using Athena;
using Athena.Tools;
using Athena.Objects;
using Athena.Core;

using WeifenLuo.WinFormsUI.Docking;
using System.Windows.Forms;

using SBW;
using Athena.SBW;

namespace Athena.Plugins
{
    public partial class SimulationControl : IGUITool
    {

        private static ZedGraph.ColorSymbolRotator _Rotator = new ZedGraph.ColorSymbolRotator();
        public static ZedGraph.ColorSymbolRotator Rotator
        {
            get { return _Rotator; }
            set { _Rotator = value; }
        }
        public override ToolManager.Order Order
        {
            get
            {
                return ToolManager.Order.FRONT;
            }
        }

        public SimulationControl()
        {
            _bRequiresNewToolWindow = true;

            InitializeComponent();

            Text = "Simulation Window";
            ToolManager.Instance.RegisterTool(Text, "Allows simulating the current model", this);

            _oZedGraphForSimulation.IsEnableSelection = false;
            _oZedGraphForSimulation.GraphPane.Title.IsVisible = false;
            _oZedGraphForSimulation.GraphPane.Legend.Position = ZedGraph.LegendPos.Right;
            _oZedGraphForSimulation.GraphPane.XAxis.Title.Text = "time";
            _oZedGraphForSimulation.GraphPane.YAxis.Title.Text = "Concentration(s)";                      

            InitOptionsForm();

            CurrentModel.ModelChanged += new Model.ModelChangedDelegate(CurrentModel_ModelChanged);
            //CurrentModel.SelectionChanged += new Model.SelectionChangedDelegate(CurrentModel_SelectionChanged);
        }

        void CurrentModel_SelectionChanged(object sender, Model.SelectionEventArgs e)
        {
            if (!IsHidden)
            {
                Core.Module targetModule = null;
                if (CurrentModel.Selected.Count > 0 && CurrentModel.Selected[0] != null)
                {
                    Core.Container c = CurrentModel.Selected[0].Item as Core.Container;
                    if (c != null)
                    {
                        if (c is Core.Module)
                            targetModule = c as Core.Module;
                        else
                            if (c.LocalItems.Count == 1 && c.LocalItems[0] is Core.Module)
                            {
                                targetModule = c.LocalItems[0] as Core.Module;
                            }
                    }
                }

                if (targetModule == null)
                    targetModule = CurrentModel.BackEndModel;

                if (Simulator.CurrentModule != targetModule ||
                        Analyzer.CurrentModule != targetModule)
                    LoadModel(targetModule);
                //else
                //    Simulator.reset();
            }
        }

        void CurrentModel_ModelChanged(object sender, EventArgs e)
        {
            try
            {
                if (CurrentModel.BackEndModel.LocalItems.Count < 1)
                {
                    _oZedGraphForSimulation.GraphPane.CurveList.Clear();
                    _oZedGraphForRatePlots.GraphPane.CurveList.Clear();
                    _oZedGraphForSimulation.Refresh();
                    _oZedGraphForRatePlots.Refresh();
                    if (Simulator != null) Simulator.CurrentModule = null;
                    if (Analyzer != null) Analyzer.CurrentModule = null;
                    return;
                }
                /*
                if (CurrentModel.Selected.Count > 0 && CurrentModel.Selected[0] != null
                    && CurrentModel.Selected[0].Item is Core.Module)
                {
                    SetSimulatorModel(CurrentModel.Selected[0].Item as Core.Module);
                    SetAnalyzerModel(CurrentModel.Selected[0].Item as Core.Module);
                }
                else
                {
                    SetSimulatorModel(CurrentModel.BackEndModel);
                    SetAnalyzerModel(CurrentModel.BackEndModel);
                }

                Simulator sim = Simulator;
                Simulator = null;

                checkBox1.Checked = true;   //show species
                checkBox2.Checked = true;   //show reactions

                Simulator = sim;

                InitializeAnalyzerColumns();
                InitializeSimulationColumns();
                UpdateRatePlots();
                */
            }
            catch (Exception)
            {
                // nevermind
            }
        }

        private SimulationControlOptions _oOptions;

        public SimulationControlOptions Options
        {
            get { return _oOptions; }
            set { _oOptions = value; }
        }


        private void InitOptionsForm()
        {
            Options = new SimulationControlOptions(this);
            Options.DockPanel = DockPanel;
            //Options.Simulator = Simulator;
            //Options.Analyzer = Analyzer;
        }

        public override void SetupDockPanel(WeifenLuo.WinFormsUI.Docking.DockPanel oPanel)
        {
            this.DockPanel = oPanel;
            DockState = DockState.DockBottom;
            Options.DockPanel = oPanel;
            oPanel.DockBottomPortion = 340;
            Hide();
        }
        public override void SetupToolStrip(ToolStrip oStrip)
        {
            ToolStripButton oButton = new ToolStripButton();
            oButton.Text = "Si&mulation ...";
            oButton.ToolTipText = "Allows Simulating the current model";
            oButton.Click += new EventHandler(ShowHide_Click);
            oStrip.Items.Add(oButton);
        }

        public override void ShowHide_Click(object sender, EventArgs e)
        {
            if (IsHidden)
            {
                //DockState = DockState.DockBottom;
                Show();
                if ((Simulator != null && Simulator.CurrentModule == null) ||
                (Analyzer != null && Analyzer.CurrentModule == null))
                {
                    if (CurrentModel.Selected.Count > 0 && CurrentModel.Selected[0] != null
                                && CurrentModel.Selected[0].Item is Core.Module)

                        LoadModel(CurrentModel.Selected[0].Item as Core.Module);
                    else
                        LoadModel(CurrentModel.BackEndModel);
                }
            }
            else
            {
                Hide();
            }
        }

        private void cmdReset_Click(object sender, EventArgs e)
        {
            _oZedGraphForSimulation.GraphPane.CurveList.Clear();
            //_oZedGraphForSimulation.AxisChange();
            _oZedGraphForSimulation.Refresh();
            if (Simulator != null)
            {
                try
                {
                    Simulator.reset();
                }
                catch (Exception)
                {
                }
            }
         
        }
        
        /// <summary>
        /// get or set the simulator to use
        /// </summary>
        public Simulator Simulator
        {
            get { return ToolManager.Instance.Simulator; }
            set { ToolManager.Instance.Simulator = value; }
        }

        /// <summary>
        /// get or set the analyzer to use. The Analyzer plots the rate functions and 
        /// the vector fields
        /// </summary>
        public Analyzer Analyzer
        {
            get { return ToolManager.Instance.Analyzer; }
            set { ToolManager.Instance.Analyzer = value; }
        }

        List<bool> _displayedCurves;
        List<string> _simulationColNames, _ratePlotsColNames;
        List<System.Drawing.Color> _colorsForSimulation, _colorsForRatePlots;

        public void InitializeSimulationColumns()
        {
            try
            {
                if (Simulator == null) return;
                if (Simulator.CurrentModule == null)
                    SetSimulatorModel(CurrentModel.BackEndModel);

                _simulationColNames = new List<string>();
                _colorsForSimulation = new List<System.Drawing.Color>();
                _Rotator = new ZedGraph.ColorSymbolRotator();
                
                ArrayList visibleItems = new ArrayList();
                visibleItems.Add("time");

                Hashtable allItems = Simulator.CurrentModule.AllItems;
                foreach (string s in allItems.Keys)
                {
                    Item item = allItems[s] as Item;
                    if (item == null || item.Drawable == null || item.Drawable.IsVisible)
                    {
                        if (item is Node || item is Edge)
                            visibleItems.Add(s);
                    }
                }

                ArrayList oSelection = SimulatorSelectionList();

                for (int i = oSelection.Count - 1; i >= 0; --i)
                {
                    if (!visibleItems.Contains(oSelection[i]))
                        oSelection.RemoveAt(i);
                }

                Simulator.setSelectionList(oSelection);

                _displayedCurves = new List<bool>();
                xaxisCmb.Items.Clear();
                if (oSelection != null)
                    foreach (string s in oSelection)
                    {

                        _simulationColNames.Add(s);
                        xaxisCmb.Items.Add(s);
                        _colorsForSimulation.Add(Rotator.NextColor);
                        _displayedCurves.Add(true);

                    }
            }
            catch (Exception)
            {
            }
        }

        void InitializeAnalyzerColumns()
        {
            try
            {
                if (Analyzer == null) return;
                if (Analyzer.CurrentModule == null)
                    SetAnalyzerModel(CurrentModel.BackEndModel);

                _Rotator = new ZedGraph.ColorSymbolRotator();
                _colorsForRatePlots = new List<System.Drawing.Color>();
                _oZedGraphForRatePlots.GraphPane.YAxis.Title.Text = "Reaction rate(s)";

                xplotsCombo.Items.Clear();
                yplotsCombo.Items.Clear();
                yphaseCombo.Items.Clear();
                xphaseCombo.Items.Clear();

                _ratePlotsColNames = new List<string>();

                ArrayList species = AnalyzerFloatingSpeciesList(),
                          reactions = AnalyzerReactionList(),
                          boundary = Analyzer.getBoundarySpeciesNames(),
                          parms = Analyzer.getGlobalParameterNames();

                yplotsCombo.Items.Add("All");

                Hashtable allItems = Analyzer.CurrentModule.AllItems;

                if (species != null)
                    foreach (string s in species)
                    {
                        xplotsCombo.Items.Add(s);
                        xphaseCombo.Items.Add(s);
                        yphaseCombo.Items.Add(s);
                        //_colorsForRatePlots.Add(Rotator.NextColor);
                    }
                foreach (string s in boundary)
                {
                    xplotsCombo.Items.Add(s);
                    //xphaseCombo.Items.Add(s);
                    //yphaseCombo.Items.Add(s);
                    //_colorsForRatePlots.Add(Rotator.NextColor); 
                }
                foreach (string s in parms)
                {
                    xplotsCombo.Items.Add(s);
                    //xphaseCombo.Items.Add(s);
                    //yphaseCombo.Items.Add(s);
                    //_colorsForRatePlots.Add(Rotator.NextColor);
                }
                foreach (string s in reactions)
                {
                    yplotsCombo.Items.Add(s);
                    _ratePlotsColNames.Add(s);
                    _colorsForRatePlots.Add(Rotator.NextColor);
                }
            }
            catch (Exception)
            {
                
            }
        }

        #region threaded methods to prevent freezes
        
        static Core.Module _CurrentModule = null;
        
        static void LoadModelIntoSimulator(object simulator)
        {
            if (simulator is Simulator)
                ((Simulator)simulator).CurrentModule = _CurrentModule;
        }

        static void LoadModelIntoAnalyzer(object analyzer)
        {
            if (analyzer is Analyzer)
                ((Analyzer)analyzer).CurrentModule = _CurrentModule;
        }

        static ArrayList _ArrayList;
        static void GetSimulatorSelectionList(object simulator)
        {
            if (simulator is Simulator)
                _ArrayList = ((Simulator)simulator).getSelectionList();
            
        }

        static void GetSimulatorFloatingSpeciesList(object simulator)
        {
            if (simulator is Simulator)
                _ArrayList = ((Simulator)simulator).getFloatingSpeciesNames();
        }

        static void GetSimulatorReactionList(object simulator)
        {
            if (simulator is Simulator)
                _ArrayList = ((Simulator)simulator).getReactionNames();
        }

        static void GetSimulatorAvailableList(object simulator)
        {
            if (simulator is Simulator)
                _ArrayList = ((Simulator)simulator).getAvailableSymbols();
        }

        static void GetAnalyzerFloatingSpeciesList(object analyzer)
        {
            if (analyzer is Analyzer)
                _ArrayList = ((Analyzer)analyzer).getFloatingSpeciesNames();
        }

        static void GetAnalyzerReactionList(object analyzer)
        {
            if (analyzer is Analyzer)
                _ArrayList = ((Analyzer)analyzer).getReactionNames();
        }

        #endregion

        public ArrayList SimulatorSelectionList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetSimulatorSelectionList));
            thread.Start(Simulator);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public ArrayList SimulatorAvailableList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetSimulatorAvailableList));
            thread.Start(Simulator);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public ArrayList AnalyzerFloatingSpeciesList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetAnalyzerFloatingSpeciesList));
            thread.Start(Analyzer);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public ArrayList SimulatorFloatingSpeciesList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetSimulatorFloatingSpeciesList));
            thread.Start(Simulator);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public ArrayList AnalyzerReactionList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetAnalyzerReactionList));
            thread.Start(Analyzer);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public ArrayList SimulatorReactionList()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(GetSimulatorReactionList));
            thread.Start(Analyzer);
            thread.Join(ToolManager.MaxSimulationTime);
            return _ArrayList;
        }

        public void SetSimulatorModel(Core.Module module)
        {
            _CurrentModule = module;
            Thread thread = new Thread(new ParameterizedThreadStart(LoadModelIntoSimulator));
            thread.Start(Simulator);
            thread.Join(ToolManager.MaxSimulationTime);
        }

        public void SetAnalyzerModel(Core.Module module)
        {
            _CurrentModule = module;
            Thread thread = new Thread(new ParameterizedThreadStart(LoadModelIntoAnalyzer));
            thread.Start(Analyzer);
            thread.Join(ToolManager.MaxSimulationTime);
        }

        public bool LoadModel(Core.Module module)
        {
            try
            {
                Simulator sim = Simulator;
                Simulator = null;

                checkBox1.Checked = true;   //show species
                checkBox2.Checked = true;   //show reactions

                Simulator = sim;

                Utility.SetMessage("initializing simulator...");

                if (Simulator == null)
                {
                    Simulator = new SBWSimulator("edu.kgi.roadRunner", "sim");
                    Options.Simulator = Simulator;
                }

                SetSimulatorModel(module);
                SetAnalyzerModel(module);                

                InitOptionsForm();

                InitializeSimulationColumns();

                InitializeAnalyzerColumns();

                Simulator.reset();

                return true;
            }
            catch (Exception)
            {
                Utility.SetMessage("Error initializing simulator");
                return false;
            }
            finally
            {
                //LowLevel.SBWConnect();
            }
        }

        public void SetUpSimulator()
        {
            try
            {
                Simulator.setNumPoints( Convert.ToInt32(txtNumPoints.Text));
                Simulator.setTimeEnd(Convert.ToDouble(txtEndTime.Text));
                Simulator.setTimeStart(Convert.ToDouble(txtStartTime.Text));
            }
            catch (Exception)
            {
                ///
            }
        }

        private bool _bEnableUpdating = true;

        public bool EnableUpdating
        {
            get { return _bEnableUpdating; }
            set { _bEnableUpdating = value; }
        }

        int _SimulateXaxis = 0, _PlotXAxis = 0;
        
        double[,] _simulationData;

        public void UpdateSimulationResults(bool changeAxis)
        {
            if (EnableUpdating)
            {
                try
                {
                    Utility.SetMessage("Simulating...");
                    _simulationData = Simulate();

                    Utility.SetMessage("Graphing results...");
                    if (_simulationColNames == null || _simulationColNames.Count < _simulationData.GetLength(1) || _colorsForSimulation == null || _colorsForSimulation.Count < _simulationData.GetLength(1))
                        InitializeSimulationColumns();

                    PrintResults(_oZedGraphForSimulation, _simulationColNames, _colorsForSimulation, _simulationData, _SimulateXaxis);
                    for (int i = 0, j = 0; i < _simulationData.GetLength(1); ++i)
                    {
                        if (i != _SimulateXaxis)
                        {
                            _oZedGraphForSimulation.GraphPane.CurveList[j].IsVisible = _displayedCurves[i];
                            ++j;
                        }
                    }
                    Utility.SetMessage("finished graphing");
                }
                catch (Exception)
                {
                    Utility.SetMessage("Error simulating the model");
                }
                finally
                {
                    if (changeAxis)
                        _oZedGraphForSimulation.AxisChange();

                    _oZedGraphForSimulation.Refresh();
                    
                }
            }
        }

        static double[,] _DataArray;
        static void DoSimulation(object simulator)
        {
            if (simulator is Simulator)
            {
                try
                {
                    _DataArray = ((Simulator)simulator).simulate();
                }
                catch (Exception)
                {
                }
            }
        }

        private double[,] Simulate()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DoSimulation));
            thread.Start(Simulator);
            thread.Join(ToolManager.MaxSimulationTime);
            return _DataArray;
        }

        private void PrintResults(ZedGraph.ZedGraphControl zedGraph, List<string> colNames, List<Color> colors, double[,] oData, int xaxis)
        {
            zedGraph.GraphPane.CurveList.Clear();

            zedGraph.GraphPane.XAxis.Scale.MinGrace = 0.0;
            zedGraph.GraphPane.XAxis.Scale.MaxGrace = 0.0;
            //_oZedGraph.GraphPane.YAxis.Scale.MinGrace = 0.0;
            //_oZedGraph.GraphPane.YAxis.Scale.MaxGrace = 5.0;
               
            for (int i = 0; i < oData.GetLength(1); i++)
            {
                if (i == xaxis) continue;
                ZedGraph.PointPairList oList = new ZedGraph.PointPairList();
                for (int j = 0; j < oData.GetLength(0); j++)
                {
                    oList.Add(oData[j, xaxis], oData[j, i]);
                }
                ZedGraph.LineItem oItem = zedGraph.GraphPane.AddCurve(colNames[i], oList, colors[i], ZedGraph.SymbolType.None);
                oItem.Line.Width *= 2f;
            }
        }

        private void cmdSimulate_Click(object sender, EventArgs e)
        {
            CurrentModel_SelectionChanged(null,null);
            SetUpSimulator();
            UpdateSimulationResults(true);
        }

        public void StartSimulation()
        {
            if (IsHidden)
                Show();

            if (CurrentModel.Selected.Count > 0 && CurrentModel.Selected[0] != null
                        && CurrentModel.Selected[0].Item is Core.Module)

                LoadModel(CurrentModel.Selected[0].Item as Core.Module);
            else
                LoadModel(CurrentModel.BackEndModel);

            SetUpSimulator();

            UpdateSimulationResults(true);

            UpdateRatePlots();
        }

        private void cmdOptions_Click(object sender, EventArgs e)
        {
            Options.Show();
        }

        private void _oZedGraph_Click(object sender, EventArgs args)
        {
            try
            {
                if (args is MouseEventArgs)
                {
                    MouseEventArgs e = args as MouseEventArgs;
                    if (e.Button == MouseButtons.Left)
                    {
                        System.Drawing.Point oPos = e.Location;
                        int nIndex = 0;
                        if (_oZedGraphForSimulation.GraphPane.Legend.FindPoint(oPos, _oZedGraphForSimulation.GraphPane, _oZedGraphForSimulation.GraphPane.CalcScaleFactor(), out nIndex))
                        {
                            if (nIndex >= _SimulateXaxis)
                                _displayedCurves[nIndex + 1] = _oZedGraphForSimulation.GraphPane.CurveList[nIndex].IsVisible = !_oZedGraphForSimulation.GraphPane.CurveList[nIndex].IsVisible;
                            else
                                _displayedCurves[nIndex] = _oZedGraphForSimulation.GraphPane.CurveList[nIndex].IsVisible = !_oZedGraphForSimulation.GraphPane.CurveList[nIndex].IsVisible;
                        }
                    }
                    _oZedGraphForSimulation.Refresh();
                }
            }
            catch (Exception) { }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                string sx = xaxisCmb.SelectedItem as string;
                if (sx == null) return;

                _oZedGraphForSimulation.GraphPane.XAxis.Title.Text = sx;

                _SimulateXaxis = xaxisCmb.SelectedIndex;

                PrintResults(_oZedGraphForSimulation, _simulationColNames, _colorsForSimulation, _simulationData, _SimulateXaxis);

                _oZedGraphForSimulation.AxisChange();
                _oZedGraphForSimulation.Refresh();
            }
            catch (Exception) { }
        }

        double[,] _VectorFields;
        /// <summary>
        /// draw phase portrait
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void vectorField_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                Graphics g = e.Graphics;
                if (_VectorFields == null) return;

                int m = _VectorFields.GetLength(0);
                int n = _VectorFields.GetLength(1);

                float dx = panel9.Width / m;
                float dy = panel9.Height / n;

                Pen pen = new Pen(Color.Black, 1f);

                for (int i = 0; i < m; ++i)
                    for (int j = 0; j < n; ++j)
                    {
                        PointF a = new PointF(i * dx - dx / 4, j * dy - dy / 4);
                        PointF b = new PointF(a.X + dx / 2, a.Y + (float)_VectorFields[i, j]);
                        g.DrawLine(pen, a, b);
                    }
            }
            catch (Exception) { }
        }

        public void UpdateRatePlots()
        {
            double start = (Convert.ToDouble(plotStart.Text));
            double end = (Convert.ToDouble(plotEnd.Text));

            int index = _PlotXAxis;

            string species = xplotsCombo.Items[index] as string;
            _oZedGraphForRatePlots.GraphPane.XAxis.Title.Text = species;

            double[,] ratePlots = Analyzer.getRatePlots(start, end, (int)((end-start)*10), species);
            List<string> colNames = new List<string>();
            List<Color> colColors = new List<Color>();

            if (yplotsCombo.SelectedIndex > 0)
            {
                string s = (string)yplotsCombo.SelectedItem;
                double[,] temp = ratePlots;
                int m = temp.GetLength(0);
                
                ratePlots = new double[m, 2];
                colColors.Add(Color.Black);
                colNames.Add(species);

                int k = 0;
                for (int i = 0; i < _ratePlotsColNames.Count; ++i)
                    if (_ratePlotsColNames[i] == s)
                    {
                        k = i+1;
                        colColors.Add(_colorsForRatePlots[i]);
                        colNames.Add(_ratePlotsColNames[i]);
                        break;
                    }

                for (int i = 0; i < m; ++i)
                {
                    ratePlots[i, 0] = temp[i, 0];
                    ratePlots[i, 1] = temp[i, k];
                }
            }
            else
            {
                colNames.Add(species);
                colNames.AddRange(_ratePlotsColNames);
                colColors.Add(Color.Black);
                colColors.AddRange(_colorsForRatePlots);
            }

            if (ratePlots != null)
            {
                PrintResults(_oZedGraphForRatePlots, colNames, colColors, ratePlots, 0);
            }
            _oZedGraphForRatePlots.AxisChange();
            _oZedGraphForRatePlots.Refresh();
        }

        private void xplotsCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (xplotsCombo.SelectedIndex > -1)
                    _PlotXAxis = xplotsCombo.SelectedIndex;
                UpdateRatePlots();
            }
            catch (Exception)
            {
            }
        }

        private void plotEnd_TextChanged(object sender, EventArgs e)
        {
            try
            {
                UpdateRatePlots();
            }
            catch (Exception)
            {
            }
        }

        private void yplotsCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                UpdateRatePlots();
            }
            catch (Exception)
            {
            }
        }

        private void yphaseCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (xphaseCombo.SelectedIndex >= 0 && yphaseCombo.SelectedIndex >= 0)
                {
                    string s1 = (string)xphaseCombo.SelectedItem;
                    string s2 = (string)yphaseCombo.SelectedItem;
                    _VectorFields = Analyzer.getPhasePortrait(s1, s2, 0, 10, 0, 10, 0.1);
                    panel9.Refresh();
                }
            }
            catch (Exception)
            {
            }
        }

        private void xphaseCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (xphaseCombo.SelectedIndex >= 0 && yphaseCombo.SelectedIndex >= 0)
                {
                    string s1 = (string)xphaseCombo.SelectedItem;
                    string s2 = (string)yphaseCombo.SelectedItem;
                    _VectorFields = Analyzer.getPhasePortrait(s1, s2, 0, 10, 0, 10, 0.5);
                    panel9.Refresh();
                }
            }
            catch(Exception)
            {
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (Simulator == null) return;
            try
            {
                ArrayList list = new ArrayList();
                list.Add("time");                
                if (checkBox1.Checked) list.AddRange(SimulatorFloatingSpeciesList());
                if (checkBox2.Checked) list.AddRange(SimulatorReactionList());
                if (!checkBox1.Checked && !checkBox2.Checked) checkBox2.Checked = true;
                else
                    if (list.Count > 0)
                    {
                        Simulator.setSelectionList(list);
                        InitializeSimulationColumns();
                        UpdateSimulationResults(true);
                    }
            }
            catch (Exception)
            {
            }
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (Simulator == null) return;
            try
            {
                ArrayList list = new ArrayList();
                list.Add("time");
                if (checkBox1.Checked) list.AddRange(SimulatorFloatingSpeciesList());
                if (checkBox2.Checked) list.AddRange(SimulatorReactionList());
                if (!checkBox1.Checked && !checkBox2.Checked) checkBox1.Checked = true;
                else
                    if (list.Count > 0)
                    {
                        Simulator.setSelectionList(list);
                        InitializeSimulationColumns();
                        UpdateSimulationResults(true);
                    }
            }
            catch (Exception)
            {
            }
        }

    }
}
